/*
 * Copyright (C) 2010 mAPPn.Inc
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.mol.market.ui_v4;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.os.Process;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.mol.market.R;
import com.mol.market.Session;
import com.mol.market.common.download.DownloadManager;
import com.mol.market.common.util.ImageUtils;
import com.mol.market.common.util.Utils;
import com.mol.market.common.vo.DownloadInfo;

import java.io.File;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * GfanClient ListView associating adapter<br>
 * It has lazyload feature, which load data on-demand.
 * 
 * @author andrew.wang
 * 
 */
public class DownloadManagerAdapter extends BaseAdapter implements Observer {

    /** 标题栏【下载中】 */
    /*package*/ static final String TITLE_DOWNLOADING = "title_downloading";
    /** 标题栏【下载完成】 */
    /*package*/ static final String TITLE_DOWNLOADED = "title_downloaded";
    /** 标题栏【队列中】 */
    /*package*/ static final String TITLE_WAITING = "title_waiting";
    
    /** 标题栏 */
    /*package*/ static final int VIEW_TYPE_TITLE = 0;
    /** 下载中项目 */
    /*package*/ static final int VIEW_TYPE_DOWNLOADING = 1;
    /** 下载完成项目 */
    /*package*/ static final int VIEW_TYPE_DOWNLOADED = 2;
    
    // 排序权重
    /*package*/static final int WEIGHT_DOWNLOADING_TITLE = 0;
    /*package*/static final int WEIGHT_DOWNLOADING_ITEM = 1;
    /*package*/static final int WEIGHT_DOWNLOADING_PENDING_ITEM = 2;
    /*package*/static final int WEIGHT_WAITING_TITLE = 3;
    /*package*/static final int WEIGHT_WAITING_ITEM = 4;
    /*package*/static final int WEIGHT_DOWNLOADING_ERROR_ITEM = 5;
    /*package*/static final int WEIGHT_DOWNLOADED_TITLE = 6;
    /*package*/static final int WEIGHT_DOWNLOADED_ITEM = 7;
    
    /** 刷新间隔时间 */
    private static final int REFRESH_INTERVAL = 200;
    
    /** 下载刷新操作 */
    private static final int REFRESH_DOWNLOADING = 0;
    
    /** 删除无效的项目 */
    private static final int REMOVING_ITEM = 1;
    
    // 列表后台数据

    private ListOrderedMap mDataSource;
    private LayoutInflater mInflater;
    private Context mContext;
    private DownloadManagerFragment mActivity;
    private Session mSession;
    /* 下载列表 */

    private ConcurrentHashMap<String, DownloadInfo> mDownloadingList;
    /* 下载管理器 */

    private DownloadManager mDownloadManager;

    /**
     * Application list adapter
     *
     * @param context
     *            application context
     * @param data
     *            the datasource behind the listview
     */
    public DownloadManagerAdapter(Context context, ListOrderedMap data) {

        if (data == null) {
          mDataSource = new ListOrderedMap();
        } else {
          mDataSource = data;
        }
        mContext = context;
        mSession = Session.get(context);
        mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        mSession.addObserver(this);
        mDownloadManager = mSession.getDownloadManager();
        mDownloadingList = mSession.getDownloadingList();
        onDownloadingChanged(mDownloadingList);
    }
    
    /**
     * 页面布局如下：
     * +--Downloading------------------+
     * + App1 (downloading)    | cancel+
     * + App2 (pending)        | cancel+
     * + ...                           +
     * +--Downloaded-------------------+
     * + App5 (downloaded)     |install+
     * +...                            +
     * +-------------------------------+
     * 
     * 刷新机制
     * 
     * [开始下载]  ->下载线程 
     *                |
     *             刷新进度(Session)
     *                |
     *             页面刷新<------- +
     *                |           |
     *                |     20    |
     *                |           |
     *             [用户取消]---N---+
     *                |
     *                Y
     *              [Stop]
     * 
     * [用户取消] － 将Task加入垃圾队列，阻止没有完成的刷新操作，完成之后从垃圾队列删除
     * 
     */

    private Handler mUiHandler = new Handler() {
      
        public void handleMessage(Message msg) {
            
            switch (msg.what) {
            
            case REFRESH_DOWNLOADING:
            
                @SuppressWarnings("unchecked")
                ArrayList<AppItem> list = (ArrayList<AppItem>) msg.obj;
                
                if (list == null || list.size() == 0) {
                    mActivity.refreshNoFiles(true);
                    return;
                }
                mActivity.refreshNoFiles(false);
                
                for (AppItem info : list) {
                    mDataSource.put(info.mPackageName, info);
                }
                notifyDataSetChanged();
                break;
                
            case REMOVING_ITEM:
                
                AppItem item = (AppItem) msg.obj;
                mDataSource.remove(item.mPackageName);
                notifyDataSetChanged();
                break;
                
            default:
                break;
            }
            
        }
    };
    
    /**
     * 刷新下载进度的任务，每200毫秒间隔执行
     */
    private void requestRefresh() {

        if (mDownloadingList == null) {
            return;
        }

        // 克隆下载列表
        HashMap<String, DownloadInfo> copyMap = new HashMap<String, DownloadInfo>(mDownloadingList);
        Collection<DownloadInfo> values = copyMap.values();

        // 新的状态列表
        ArrayList<AppItem> newStatusList = new ArrayList<AppItem>();

        // 下载队列中的项目数
        int pendingCounter = 0;
        // 下载中的项目数
        int downloadingCounter = 0;
        // 下载完成的项目数
        int downloadedCounter = 0;

        Set<String> trash = new HashSet<String>(mDataSource.map.keySet());
        for (DownloadInfo info : values) {

            AppItem item = mDataSource.getValue(info.mPackageName);
            if (item == null) {
                item = new AppItem();
                item.mAppName = info.mAppName;
                item.mPackageName = info.mPackageName;
                item.mKey = info.mKey;
                item.mIcon = info.mIconUrl;
            }
            item.mId = info.id;

            // 刷新最新的状态, 将DownloadInfo转换成AppItem
            if (DownloadManager.Impl.isStatusRunning(info.mStatus)) {
                // 下载中的项目
                downloadingCounter++;
                item.mViewType = VIEW_TYPE_DOWNLOADING;
                item.mWeight = WEIGHT_DOWNLOADING_ITEM;
                item.mProgress = info.mProgressNumber;
                item.mInfo = Utils.calculateRemainBytes(mContext, info.mCurrentSize,
                        info.mTotalSize);
            } else if (DownloadManager.Impl.isStatusPaused(info.mStatus)
                       || DownloadManager.Impl.isStatusWaiting(info.mControl)) {
                // 下载队列中的项目
                pendingCounter++;
                item.mViewType = VIEW_TYPE_DOWNLOADED;
                item.mWeight = WEIGHT_WAITING_ITEM;
                item.mInfo = mContext.getString(R.string.download_waiting_info);
                
            } else if (DownloadManager.Impl.isStatusError(info.mStatus)) {
                // 下载失败的项目
                pendingCounter++;
                item.mViewType = VIEW_TYPE_DOWNLOADED;
                item.mWeight = WEIGHT_DOWNLOADING_ERROR_ITEM;
                item.mInfo = mContext.getString(R.string.download_error_info);
                item.mInfo2 = mContext.getString(R.string.download_already, info.mProgress);
                
            } else if (DownloadManager.Impl.isStatusPending(info.mStatus)) {
                // 下载等待的项目
                downloadingCounter++;
                item.mViewType = VIEW_TYPE_DOWNLOADING;
                item.mWeight = WEIGHT_DOWNLOADING_PENDING_ITEM;
                item.mProgress = -1;
                item.mInfo = mContext.getString(R.string.download_try);

            } else if (info.mStatus == DownloadManager.Impl.STATUS_SUCCESS) {
                // 下载成功的项目
                if (!TextUtils.isEmpty(info.mFilePath) 
                        && !new File(info.mFilePath).exists()) {
                    // 文件已经被删除
                    continue;
                }
                
                downloadedCounter++;
                item.mViewType = VIEW_TYPE_DOWNLOADED;
                item.mWeight = WEIGHT_DOWNLOADED_ITEM;
                item.mFilePath = info.mFilePath;
                item.mInfo = mContext.getString(R.string.download_over);
                item.mInfo2 = null;
                
            } else {
                // 其它未知状态
                continue;
            }

            // 加入更新队列
            newStatusList.add(item);
            trash.remove(item.mKey);
        }
        
        // 处理过期的消息
        for (String key : trash) {
            
            if (key.equals(TITLE_DOWNLOADING) 
                    || key.equals(TITLE_WAITING)
                    || key.equals(TITLE_DOWNLOADED)) {
                continue;
            }
            AppItem errorItem = new AppItem();
            errorItem.mPackageName = key;
            Message msg = mUiHandler.obtainMessage();
            msg.obj = errorItem;
            msg.what = REMOVING_ITEM;
            mUiHandler.sendMessage(msg);
        }
        
        if (pendingCounter > 0) {
            // 有队列中的项目，添加【队列中】标题
            AppItem group = new AppItem();
            group.mTitle = mContext.getString(R.string.download_waiting);
            group.mInfo = mContext.getString(R.string.app_counter, pendingCounter);
            group.mViewType = VIEW_TYPE_TITLE;
            group.mWeight = WEIGHT_WAITING_TITLE;
            group.mPackageName = TITLE_WAITING;
            newStatusList.add(group);
        } else {
            // 没有队列中的项目，删除【队列中】标题
            AppItem group = new AppItem();
            group.mPackageName = TITLE_WAITING;
            Message msg = mUiHandler.obtainMessage();
            msg.obj = group;
            msg.what = REMOVING_ITEM;
            mUiHandler.sendMessage(msg);
        }

        if (downloadingCounter > 0) {
            // 有正在下载的项目，添加【下载中】标题
            AppItem group = new AppItem();
            group.mTitle = mContext.getString(R.string.all_downloading);
            group.mInfo = mContext.getString(R.string.app_counter, downloadingCounter);
            group.mViewType = VIEW_TYPE_TITLE;
            group.mWeight = WEIGHT_DOWNLOADING_TITLE;
            group.mPackageName = TITLE_DOWNLOADING;
            newStatusList.add(group);
        } else {
            // 没有正在下载的项目，删除【下载中】标题
            AppItem group = new AppItem();
            group.mPackageName = TITLE_DOWNLOADING;
            Message msg = mUiHandler.obtainMessage();
            msg.obj = group;
            msg.what = REMOVING_ITEM;
            mUiHandler.sendMessage(msg);
        }

        if (downloadedCounter > 0) {
            // 有下载完成的项目，添加【下载完成】标题
            AppItem group = new AppItem();
            group.mTitle = mContext.getString(R.string.all_downloaded);
            group.mInfo = mContext.getString(R.string.app_counter, downloadedCounter);
            group.mViewType = VIEW_TYPE_TITLE;
            group.mWeight = WEIGHT_DOWNLOADED_TITLE;
            group.mPackageName = TITLE_DOWNLOADED;
            newStatusList.add(group);
        } else {
            // 没有下载完成的项目，删除【下载完成】标题
            AppItem group = new AppItem();
            group.mPackageName = TITLE_DOWNLOADED;
            Message msg = mUiHandler.obtainMessage();
            msg.obj = group;
            msg.what = REMOVING_ITEM;
            mUiHandler.sendMessage(msg);
        }

        // 让主线程刷新数据
        Message msg = mUiHandler.obtainMessage();
        msg.what = REFRESH_DOWNLOADING;
        msg.obj = newStatusList;
        mUiHandler.sendMessage(msg);
    }
    
    /*
     * 取消下载任务
     */
    /* package */void cancelDownloadItem(AppItem item) {

        DownloadInfo data = mDownloadingList.get(item.mKey);
        if (data == null) {
            return;
        }
        data.mStatus = DownloadManager.Impl.STATUS_CANCELED;
        mDownloadManager.cancelDownload(item.mId);
        mSession.removeStarted(item.mPackageName);
        // 添加到垃圾队列，并取消下载
        Message msg = mUiHandler.obtainMessage();
        msg.obj = item;
        msg.what = REMOVING_ITEM;
        mUiHandler.sendMessage(msg);
    }

    /**
     *  暂停下载任务
     */
    /* package */ void pauseDownloadItem(AppItem item) {

        DownloadInfo data = mDownloadingList.get(item.mKey);
        if (data == null) {
          return;
        }
        data.mControl = DownloadManager.Impl.CONTROL_PENDING;
        mDownloadManager.pauseDownload(item.mId);
    }
    
//    /**
//     * 取消下载任务
//     */
//    /* package */void cancelDownloadItem(int pos) {
//
//        AppItem item = mDataSource.getValue(pos);
//        cancelDownloadItem(item);
//    }

    /*
     * How many items are in the data set represented by this Adapter.
     */
    @Override
    public int getCount() {
        if (mDataSource == null) {
            return 0;
        }
        return mDataSource.size();
    }


    @Override
    public Object getItem(int position) {

        if (mDataSource != null && position < getCount()) {
            return mDataSource.getValue(position);
        }
        return null;
    }

    @Override
    public long getItemId(int position) {
        return position;
    }

    @Override
    public boolean isEmpty() {
        if (mDataSource == null || mDataSource.size() == 0) {
            return true;
        }
        return super.isEmpty();
    }

    @Override
    public boolean areAllItemsEnabled() {
        return false;
    }

//    /*
//    * Clear all the data
//     */
//    public void clearData() {
//      if (mDataSource != null) {
//        mDataSource.clear();
//        notifyDataSetChanged();
//      }
//    }

    @Override
    public int getItemViewType(int position) {
        
        AppItem item = mDataSource.getValue(position);
        return item == null ? VIEW_TYPE_DOWNLOADED : item.mViewType;
    }

    /*
     * Return the view types of the list adapter
     */
    @Override
    public int getViewTypeCount() {
        return 3;
    }

    @Override
    public boolean isEnabled(int position) {
        return !isPlaceHolder(position);
    }
    

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View v;
        AppItem item = mDataSource.getValue(position);
        int viewType = item.mViewType;

        if (convertView == null) {
            v = newView(position, parent, viewType);
        } else {
            
            Object value = convertView.getTag(R.id.view_type);
            Integer type = -1;
            if (value instanceof Integer) {
                type = (Integer) value;
            }

            // 多线程可能导致的数据不同步
            if (viewType != type) {
                v = newView(position, parent, viewType);
            } else {
                v = convertView;
            }
        }
        bindView(position, v, viewType);
        return v;
    }
    
    public void setActivity(DownloadManagerFragment activity) {
        this.mActivity = activity;
    }
    
    /*
     * Create new view object and cache some views associated with it
     */

    private View newView(int position, ViewGroup parent, int viewType) {
        
        View v = null;
        View[] holder = null;
        
        if (viewType == VIEW_TYPE_TITLE) {
            
            v = mInflater.inflate(R.layout.activity_apps_manager_list_separator, parent, false);
            holder = new View[2];
            holder[0] = v.findViewById(R.id.title);
            holder[1] = v.findViewById(R.id.info);
            v.setTag(R.id.view_type, VIEW_TYPE_TITLE);

        } else if (viewType == VIEW_TYPE_DOWNLOADING) {

            v = mInflater.inflate(R.layout.activity_apps_manager_downloading_item, parent, false);
            holder = new View[5];
            holder[0] = v.findViewById(R.id.iv_logo);
            holder[1] = v.findViewById(R.id.tv_name);
            holder[2] = v.findViewById(R.id.progressbar);
            holder[3] = v.findViewById(R.id.tv_info);
            holder[4] = v.findViewById(R.id.tv_operation);
            v.setTag(R.id.view_type, VIEW_TYPE_DOWNLOADING);

        } else if (viewType == VIEW_TYPE_DOWNLOADED) {

            v = mInflater.inflate(R.layout.activity_apps_manager_uninstalled_item, parent, false);
            holder = new View[5];
            holder[0] = v.findViewById(R.id.iv_logo);
            holder[1] = v.findViewById(R.id.tv_name);
            holder[2] = v.findViewById(R.id.tv_info);
            holder[3] = v.findViewById(R.id.tv_info_size);
            holder[4] = v.findViewById(R.id.tv_operation);
            v.setTag(R.id.view_type, VIEW_TYPE_DOWNLOADED);

        }

        if (v != null) {
            v.setTag(holder);
        }
        return v;
    }
    
    /*
     * bind the background data to the view
     */
    private void bindView(int position, View view, int viewType) {

        final AppItem item = mDataSource.getValue(position);
        if (item == null) {
            return;
        }
        final View[] holder = (View[]) view.getTag();
        if (viewType == VIEW_TYPE_TITLE) {

            bindTitleView(holder, item);

        } else if (viewType == VIEW_TYPE_DOWNLOADING) {

            bindDownloadingView(position, holder, item);
            
        } else if (viewType == VIEW_TYPE_DOWNLOADED) {

            bindUninstalledView(position, holder, item);
            
        }
    }
    
    /*
     * Bind views for downloading item
     */
    private void bindDownloadingView(int position, View[] holder, AppItem item) {

        ImageView iconView = (ImageView) holder[0];
        if (item.mIcon instanceof Drawable) {
            setImageView(iconView, (Drawable) item.mIcon);
        } else if (item.mIcon instanceof String) {
            setImageView(iconView, (String) item.mIcon, true);
        }
        // 2012/8/21 0.9.5添加点击暂停下载的功能
        iconView.setTag(position);
        iconView.setOnClickListener(mOperationListener);

        setTextView((TextView) holder[1], item.mAppName);

        setProgressBar((ProgressBar) holder[2], item.mProgress);

        setTextView((TextView) holder[3], item.mInfo);

        setTextView(position, (TextView) holder[4], item.mWeight);
    }
    
    /*
     * Bind views for uninstalled item
     */
    private void bindUninstalledView(int position, View[] holder, AppItem item) {

        if (item.mIcon instanceof Drawable) {
            setImageView((ImageView) holder[0], (Drawable) item.mIcon);
        } else if (item.mIcon instanceof String) {
            setImageView((ImageView) holder[0], (String) item.mIcon, false);
        }

        setTextView((TextView) holder[1], item.mAppName);

        setTextView((TextView) holder[2], item.mInfo);

        setTextView((TextView) holder[3], item.mInfo2);
        
        setTextView(position, (TextView) holder[4], item.mWeight);
    }
    
    
    /*
     * Bind views for splitter item
     */
    private void bindTitleView(View[] holder, AppItem item) {
        
        // left info
        setTextView((TextView) holder[0], item.mTitle);
        
        // right info
        setTextView((TextView) holder[1], item.mInfo);
    }
    
    private static void setTextView(TextView v, CharSequence text) {

        if (!TextUtils.isEmpty(text)) {
            v.setText(text);
            v.setVisibility(View.VISIBLE);
        } else
            v.setVisibility(View.GONE);
    }
    
    /*
     * Bind CompoundDrawable TextView
     */
    private void setTextView(int position, TextView v, int weight) {

        if (WEIGHT_DOWNLOADED_ITEM == weight) {

            AppItem item = mDataSource.getValue(position);
            if (!TextUtils.isEmpty(item.mFilePath)) {
                // 下载完成
                v.setText(R.string.download_status_downloaded);
                v.setCompoundDrawablesWithIntrinsicBounds(null, mContext.getResources()
                        .getDrawable(R.drawable.down_btn_9), null, null);
                v.setVisibility(View.VISIBLE);
            }
        } else if (WEIGHT_WAITING_ITEM == weight) {
            
            v.setText(R.string.label_start_short);
            v.setCompoundDrawablesWithIntrinsicBounds(null,
                    mContext.getResources().getDrawable(R.drawable.down_btn_12), null, null);
            v.setVisibility(View.VISIBLE);
            
        } else if (WEIGHT_DOWNLOADING_ITEM == weight 
                || WEIGHT_DOWNLOADING_PENDING_ITEM == weight) {
            v.setText(R.string.cancel_downloads);
            v.setCompoundDrawablesWithIntrinsicBounds(null,
                    mContext.getResources().getDrawable(R.drawable.btn_uninstall), null, null);
            v.setVisibility(View.VISIBLE);
            
        } else if (WEIGHT_DOWNLOADING_ERROR_ITEM == weight) {
            
            v.setText(R.string.retry);
            v.setCompoundDrawablesWithIntrinsicBounds(null,
                    mContext.getResources().getDrawable(R.drawable.down_btn_12), null, null);
            v.setVisibility(View.VISIBLE);
            
        } else {
            v.setVisibility(View.INVISIBLE);
        }
        v.setTag(position);
        v.setOnClickListener(mOperationListener);
        v.setFocusable(false);
        v.setFocusableInTouchMode(false);
    }
    
    /*
     * Utility for ImageView(get rid of old drawable)
     */
    private static void setImageView(ImageView v, Drawable drawable) {
        
        v.setVisibility(View.VISIBLE);
        Drawable old = v.getDrawable();
        if (old != null) {
            old.setCallback(null);
        }
        v.setImageDrawable(drawable);
    }
    
    /*
     * Utility for ImageView(get rid of old drawable)
     */
    private void setImageView(ImageView v, String url, boolean isMask) {
        
        v.setVisibility(View.VISIBLE);
        Drawable old = v.getDrawable();
        if (old != null) {
            old.setCallback(null);
        }

        if (url.startsWith("http") ||
                url.startsWith("HTTP")) {
            ImageUtils.download(mContext, url, v, isMask);
        } else {
            ImageUtils.download(mContext, url, v, R.drawable.loading_icon);
        }
        
    }
    
    /*
     * Utility for ProgressBar
     */
    private static void setProgressBar(ProgressBar v, int progress) {
        
        if (progress < 0) {
            v.setIndeterminate(true);
            v.setVisibility(View.VISIBLE);
        } else {
            v.setIndeterminate(false);
            v.setProgress(progress);
            v.setVisibility(View.VISIBLE);
        }
    }
    
    private long mLastModified;
    private long mRefreshTime;
    private boolean mIsRefreshing;

    private class RefreshThread extends Thread {

        @Override
        public void run() {

            mIsRefreshing = true;

            for (;;) {

                try {
                    Thread.sleep(REFRESH_INTERVAL);
                } catch (InterruptedException e) {
                    Utils.E("refresh downloading apps", e);
                }

                if (mLastModified < mRefreshTime) {
                    break;
                }
                mRefreshTime = System.currentTimeMillis();

                // 刷新下载中的项目
                requestRefresh();
            }

            mIsRefreshing = false;
        }
    }
    
    /*
     * Operation Listener
     */

    private OnClickListener mOperationListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            int position = (Integer) v.getTag();
            
            if (position >= mDataSource.size()) {
                return;
            }
            final AppItem item = mDataSource.getValue(position);
            
            if (item.mWeight == WEIGHT_WAITING_ITEM) {
                
                DownloadInfo info = mDownloadingList.get(item.mPackageName);
                if (info != null) {
                    mDownloadManager.resumeDownload(info.id);
                }
                
            } else if (item.mWeight == WEIGHT_DOWNLOADING_ERROR_ITEM) {
                
                DownloadInfo info = mDownloadingList.get(item.mPackageName);
                if (info != null) {
                    mDownloadManager.restartDownload(info.id);
                }
                
            } else if (item.mWeight == WEIGHT_DOWNLOADED_ITEM) {
                
                // 安装应用
                if (!TextUtils.isEmpty(item.mFilePath)) {

                    if (new File(item.mFilePath).exists()) {
                        // 判断签名
                        judgeInstallStatus(item);
                    } else {
                        // 文件已经被删除
                        Utils.makeEventToast(mContext,
                                mContext.getString(R.string.install_fail_file_not_exist), false);
                    }
                }
                
            } else if (item.mWeight == WEIGHT_DOWNLOADING_ITEM
                    || item.mWeight == WEIGHT_DOWNLOADING_PENDING_ITEM) {

                  if (v.getId() == R.id.iv_logo) {
                      // 点击产品ICON，暂停下载
                      pauseDownloadItem(item);
                  } else {
                      // 取消下载
                      cancelDownloadItem(item);
                  }
            }
        }
    };
    
    /*
     * 判断是否签名一致并安装
     */
    private void judgeInstallStatus(final AppItem item) {
        if (!TextUtils.isEmpty(item.mFilePath)) {
            // 已经下载
            if (Utils.compareFileWithPathAndPkg(mContext, item.mFilePath, item.mPackageName)) {
                Utils.installApk(mContext, new File(item.mFilePath));
                return;
            }

            // TODO
//            if (!mActivity.isFinishing()) {
//                DialogUtil.createComfirmDownloadDialog(mActivity.getParent(), false,
//                        new WarningDialogListener() {
//
//                            @Override
//                            public void onWarningDialogOK(int id) {
//                                mSession.mNotSameApps.put(item.mPackageName, item.mFilePath);
//                                Utils.uninstallApk(mContext, item.mPackageName);
//                            }
//
//                            @Override
//                            public void onWarningDialogCancel(int id) {
//                            }
//
//                        }).show();
//            }
        } 
    }
    
    /*
     * Identify whether current item is only a place holder
     */
    private boolean isPlaceHolder(int position) {
        if (mDataSource == null) {
            return false;
        }

        if (position >= mDataSource.size()) {
            return false;
        }

        AppItem item = mDataSource.getValue(position);
        return item.mViewType == VIEW_TYPE_TITLE;
    }

    private void onDownloadingChanged(final ConcurrentHashMap<String, DownloadInfo> list) {

        synchronized (DownloadManagerAdapter.this) {
            mDownloadingList = list;
        }
        mLastModified = System.currentTimeMillis();
        
        if (!mIsRefreshing) {
            RefreshThread refreshThread = new RefreshThread();
            refreshThread.setPriority(Process.THREAD_PRIORITY_BACKGROUND);
            refreshThread.start();
        }
    }

    @SuppressWarnings("unchecked")
    @Override
    public void update(Observable arg0, Object arg1) {
        
        if (arg1 instanceof ConcurrentHashMap) {
            onDownloadingChanged((ConcurrentHashMap<String, DownloadInfo>) arg1);
        }
    }
    
//    /**
//     * 安装一个应用
//     */
//    /* package */void installAppWithPackageName(final String packageName) {
//
//        AppItem item = mDataSource.getValue(packageName);
//
//        if (item == null) {
//            return;
//        }
//
//        if (mSession.isAutoDelete() && !TextUtils.isEmpty(item.mFilePath)) {
//            // 自动删除安装完的APK文件
//            new File(item.mFilePath).delete();
//        }
//
//        Message msg = mUiHandler.obtainMessage();
//        msg.obj = item;
//        msg.what = REMOVING_ITEM;
//        mUiHandler.sendMessage(msg);
//    }
    
    /* package */void delApp(AppItem target) {
        AppItem item = mDataSource.getValue(target.mPackageName);
        if (item != null) {
            mDownloadManager.deleteDownloadedFile(item.mId);
            Message msg = mUiHandler.obtainMessage();
            msg.obj = item;
            msg.what = REMOVING_ITEM;
            mUiHandler.sendMessage(msg);
        }
    }
    
    /* package */void close() {
        mSession.deleteObserver(this);
        mDownloadingList = null;
        mDownloadManager = null;
    }
    
    /**
     * 应用列表项<br>
     * 
     * 列表采用LinkedHashMap结构，Key是每个应用包名，Value是每个列表项，提高更新查找效率。<br>
     * 
     * @author Andrew
     * @date 2011-5-18
     */
    public static class AppItem {
        /** 数据库ID */
        public long mId;
        /** Map Key */
        public String mKey;
        /** 产品ID(用于检查更新时，判断此应用是否存在于机锋市场) */
        public String mProductId;
        /** Title(Left信息) */
        public String mTitle;
        /** Info(Right信息) */
        public String mInfo;
        /** Info(Extra信息) */

        public String mInfo2;
        /** 应用名 */
        public CharSequence mAppName;
        /** 包名 */
        public String mPackageName;
        /** ICON(Drawable或者url) */
        public Object mIcon;
        /** 存储自定义数据 */
        public Object mData;
        /** 当前版本 */
        public String mCurrentVersion;
        /** 当前版本（装饰后字符串） */
        public String mCurrentVersionString;
        /** 升级版本 */
        public String mNewVersion;
        /** 升级版本（装饰后字符串） */
        public String  mNewVersionString;
        /** 文件路径 */
        public String mFilePath;
        /** 列表项权重（用来排序） */
        public int mWeight;
        /** 下载项目的进度 */
        public int mProgress;
        /** 列表项的视图种类（本地已安装、下载中、下载完成...） */
        public int mViewType;
        /** 标识是否更新项目*/
        public boolean mIsUpdate;
        /** 更新签名 */
        public String mRsaMd5;
        /** 是否系统级应用 */
        public boolean mIsSystemApp;
        

        @Override
        public String toString() {
            return "[" + mAppName + "] weight " + mWeight + " viewType " + mViewType;
        }
    }

    public static class ListOrderedMap {
        /** The content map */
        private HashMap<String, AppItem> map;
        private ArrayList<AppItem> list;
        private Comparator<AppItem> mSortComparator;
        private boolean isRefreshed;
        
        public ListOrderedMap() {
            map = new HashMap<String, AppItem>();
            mSortComparator = new Comparator<AppItem>() {
                @Override
                public int compare(AppItem object1, AppItem object2) {
                    int weight1 = object1.mWeight;
                    int weight2 = object2.mWeight;

                    return weight1 - weight2;
                }
            };
        }

        public AppItem put(String key, AppItem value) {
            synchronized (map) {
                isRefreshed = false;
                return map.put(key, value);
            }
        }

        public AppItem remove(String key) {
            synchronized (map) {
                isRefreshed = false;
                return map.remove(key);
            }
        }
        
        public void clear() {
            synchronized (map) {
                isRefreshed = false;
                map.clear();
                list.clear();
            }
        }
        
        public AppItem getValue(int index) {
            synchronized (map) {
                while (!isRefreshed) {
                    refresh();
                }
                return list.get(index);
            }
        }
        
        public AppItem getValue(String key) {
            synchronized (map) {
                return map.get(key);
            }
        }
        
        private void refresh() {
            synchronized (map) {
                Collection<AppItem> values = map.values();
                if (values == null) {
                    return;
                }
                ArrayList<AppItem> tempList = new ArrayList<AppItem>(values);
                Collections.sort(tempList, mSortComparator);
                list = tempList;
                isRefreshed = true;
            }
        }
        
        public int size() {
            synchronized (map) {
                return map.size();
            }
        }
    }
}